import { DocumentEventCenter } from "../base_frame/DocumentEventCenter";
import { IShaderBase } from "../base_frame/IShaderBase";
import { Keyboard } from "../base_frame/Keyboard";
import { ShaderBase } from "../base_frame/ShaderBase";
import { Vector3 } from "../base_frame/math/Vector3";

export class LightCubeBase extends ShaderBase implements IShaderBase {


    protected a_Position: number;
    protected a_Color: number;
    protected a_Normal: number;

    protected u_LightDir: WebGLUniformLocation;
    protected u_LightColor: WebGLUniformLocation;
    protected u_AmbientColor: WebGLUniformLocation;

    protected readonly VS: string =
        "attribute vec4 a_Position;\n" +
        "attribute vec4 a_Color;\n" +
        "attribute vec4 a_Normal;\n" +
        "uniform mat4 u_MvpMatrix;\n" +
        "uniform vec3 u_LightDir;\n" +
        "uniform vec3 u_LightColor;\n" +
        "uniform vec3 u_AmbientColor;\n" +
        "varying vec4 v_Color;\n" +
        "void main(){\n" +
        "   vec3 normal = normalize(a_Normal.xyz);\n" +
        "   vec3 diffColor = max(dot(u_LightDir, normal),0.0) * u_LightColor * a_Color.rgb;\n" + // 漫反射
        "   vec3 ambientColor = u_AmbientColor * a_Color.rgb;\n" + // 环境光
        "   v_Color = vec4(diffColor+ambientColor,a_Color.a);\n" + // 反射光//vec4(ambientColor + diffColor, a_Color.a);
        // "   a_Position.x = a_Position.x+2.0;\n" +
        "   gl_Position = u_MvpMatrix * a_Position;\n" + // 反射光  // 没有引用到的属性值会被剔除掉
        "}\n";

    protected readonly FS: string =
        "precision mediump float;\n" +
        "varying vec4 v_Color;\n" +
        "void main(){\n" +
        "   gl_FragColor = v_Color;\n" +
        "}\n";

    private _count: number;
    lightDirVec3: any = new Vector3(0.5, 0.3, 4.0);
    rotaMatrix: Matrix4 = new Matrix4();

    init(gl: WebGL2RenderingContext | WebGLRenderingContext): void {
        if (!initShaders(gl, this.VS, this.FS)) return console.error("init shader fail");
        this.initRef(gl);
        this.initValue(gl);
        this._count = this.initBuffer(gl);
    }

    

    initValue(gl: WebGL2RenderingContext | WebGLRenderingContext) {
        let vec3 = this.lightDirVec3;
        this.moduleMatrix.setTranslate(2.0,0.0,0.0);
        vec3.normalize();  // 需要归一化方向向量
        gl.uniform3f(this.u_LightDir, vec3.x, vec3.y, vec3.z);
        gl.uniform3f(this.u_LightColor, 1.0, 1.0, 1.0);
        gl.uniform3f(this.u_AmbientColor, 0.2, 0.2, 0.2);
    }

    initRef(gl: WebGL2RenderingContext | WebGLRenderingContext): void {
        //@ts-ignore
        let program = gl.program;
        this.a_Position = gl.getAttribLocation(program, "a_Position");
        this.a_Color = gl.getAttribLocation(program, "a_Color");
        this.a_Normal = gl.getAttribLocation(program, "a_Normal");
        this.u_LightDir = gl.getUniformLocation(program, "u_LightDir");
        this.u_LightColor = gl.getUniformLocation(program, "u_LightColor");
        this.u_AmbientColor = gl.getUniformLocation(program, "u_AmbientColor");
    }

    initBuffer(gl: WebGL2RenderingContext | WebGLRenderingContext) {
        // Create a cube
        //    v6----- v5
        //   /|      /|
        //  v1------v0|
        //  | |     | |
        //  | |v7---|-|v4
        //  |/      |/
        //  v2------v3

        var vertices = new Float32Array([   // Vertex coordinates
            1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0,  // v0-v1-v2-v3 front
            1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0,  // v0-v3-v4-v5 right
            1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0,  // v0-v5-v6-v1 up
            -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0,  // v1-v6-v7-v2 left
            -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0,  // v7-v4-v3-v2 down
            1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0   // v4-v7-v6-v5 back
        ]);

        var colors = new Float32Array([     // Colors
            0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0,  // v0-v1-v2-v3 front(blue)
            0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4,  // v0-v3-v4-v5 right(green)
            1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4, 1.0, 0.4, 0.4,  // v0-v5-v6-v1 up(red)
            1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4,  // v1-v6-v7-v2 left
            1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v7-v4-v3-v2 down
            0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0, 0.4, 1.0, 1.0   // v4-v7-v6-v5 back
        ]);
        // var colors = new Float32Array([     // Colors
        //     1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v0-v1-v2-v3 front(blue)
        //     1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v0-v3-v4-v5 right(green)
        //     1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v0-v5-v6-v1 up(red)
        //     1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v1-v6-v7-v2 left
        //     1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,  // v7-v4-v3-v2 down
        //     1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0   // v4-v7-v6-v5 back
        // ]);

        var indices = new Uint8Array([       // Indices of the vertices
            0, 1, 2, 0, 2, 3,    // front
            4, 5, 6, 4, 6, 7,    // right
            8, 9, 10, 8, 10, 11,    // up
            12, 13, 14, 12, 14, 15,    // left
            16, 17, 18, 16, 18, 19,    // down
            20, 21, 22, 20, 22, 23     // back
        ]);

        var normals = new Float32Array([        // normals of the vertices
            0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, // v0-v1-v2-v3
            1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, // v0-v3-v4-v5
            0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, // v0-v5-v6-v1 up
            -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, // v1-v6-v7-v2 left
            0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, // v7-v4-v3-v2 down
            0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0 //v4-v7-v6-v5 back
        ]);

        this._createBuffer(this.a_Position, 3, gl.FLOAT, vertices, gl);
        this._createBuffer(this.a_Color, 3, gl.FLOAT, colors, gl);
        this._createBuffer(this.a_Normal, 3, gl.FLOAT, normals, gl);
        let buffer = gl.createBuffer();
        if (buffer) {
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
            gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STREAM_DRAW);
        }
        return indices.length;
    }

    private _createBuffer(index: number, size: number, type: number, datas: any, gl: WebGL2RenderingContext | WebGLRenderingContext) {
        let buffer = gl.createBuffer();
        if (!buffer) return false;
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
        gl.bufferData(gl.ARRAY_BUFFER, datas, gl.STREAM_DRAW);
        gl.vertexAttribPointer(index, size, type, false, 0, 0);
        gl.enableVertexAttribArray(index);
        return true;
    }

    inputBlur(text: string): void {

    }

    draw(gl: WebGL2RenderingContext | WebGLRenderingContext): void {

        gl.drawElements(gl.TRIANGLES, this._count, gl.UNSIGNED_BYTE, 0);
    }

}